জাভার Stream API ডেটা প্রসেসিংয়ের জন্য একটি শক্তিশালী টুল যা Sequential এবং Parallel Streams এ কাজ করতে পারে। উভয়ই ডেটা প্রসেসিংয়ে কার্যকর হলেও, তাদের ব্যবহার এবং পারফরম্যান্সে বড় পার্থক্য রয়েছে।
Sequential Stream
Sequential Stream ডেটা প্রসেসিং ধাপে ধাপে সম্পন্ন করে, যেখানে প্রতিটি ধাপ পরবর্তী ধাপ শুরু হওয়ার আগে শেষ হয়। এটি সিঙ্গেল থ্রেড ব্যবহার করে।
বৈশিষ্ট্য:
- সিঙ্গল থ্রেড: Sequential Stream সব অপারেশন একক থ্রেডে সম্পন্ন করে।
- অর্ডার মেইন্টেন: ডেটা প্রসেসিং সর্বদা উৎসের ক্রম অনুযায়ী হয়।
- কমপ্লেক্স নয়: সিম্পল এবং ডিবাগিং সহজ।
উদাহরণ:
import java.util.stream.IntStream;
public class SequentialStreamExample {
public static void main(String[] args) {
System.out.println("Sequential Stream:");
IntStream.range(1, 10)
.forEach(i -> System.out.println(Thread.currentThread().getName() + " : " + i));
}
}
আউটপুট (সম্ভাব্য):
Sequential Stream:
main : 1
main : 2
main : 3
...
main : 9
ব্যাখ্যা: main থ্রেড Sequential Stream এর সব কাজ সম্পন্ন করে।
Parallel Stream
Parallel Stream ডেটা প্রসেসিং মাল্টিপল থ্রেডে বিভক্ত করে। এটি ForkJoinPool ব্যবহার করে Parallel Processing পরিচালনা করে।
বৈশিষ্ট্য:
- মাল্টিপল থ্রেড: Parallel Stream কাজকে একাধিক থ্রেডে ভাগ করে।
- পারফরম্যান্স উন্নতি: বড় ডেটাসেটের জন্য দ্রুত কাজ সম্পন্ন করে।
- অর্ডার অপরিহার্য নয়: কিছু ক্ষেত্রে উৎস ক্রম মেইন্টেন না-ও হতে পারে।
উদাহরণ:
import java.util.stream.IntStream;
public class ParallelStreamExample {
public static void main(String[] args) {
System.out.println("Parallel Stream:");
IntStream.range(1, 10)
.parallel()
.forEach(i -> System.out.println(Thread.currentThread().getName() + " : " + i));
}
}
আউটপুট (সম্ভাব্য):
Parallel Stream:
ForkJoinPool.commonPool-worker-3 : 1
main : 2
ForkJoinPool.commonPool-worker-5 : 3
...
ব্যাখ্যা: একাধিক থ্রেড ব্যবহার করে কাজ দ্রুত সম্পন্ন হয়।
Sequential এবং Parallel Streams এর মধ্যে পার্থক্য
| বৈশিষ্ট্য | Sequential Stream | Parallel Stream |
|---|---|---|
| থ্রেড ব্যবহারে কৌশল | সিঙ্গল থ্রেড | মাল্টিপল থ্রেড |
| অর্ডার মেইন্টেন | উৎস ক্রম অনুযায়ী ডেটা প্রসেস করে | সবসময় উৎস ক্রম মেইন্টেন করে না |
| পারফরম্যান্স | ছোট ডেটাসেটের জন্য কার্যকর | বড় ডেটাসেটের জন্য কার্যকর |
| কোড সিম্প্লিসিটি | সহজ এবং ডিবাগিং সহজ | ডিবাগিং কিছুটা কঠিন |
| উদ্দেশ্য | ছোট ডেটাসেট এবং সিঙ্গেল-থ্রেড প্রসেসিং | বড় ডেটাসেট এবং মাল্টি-থ্রেড প্রসেসিং |
Sequential এবং Parallel Streams এর পারফরম্যান্স তুলনা
কোড: Sequential বনাম Parallel
import java.util.stream.LongStream;
public class StreamPerformanceComparison {
public static void main(String[] args) {
long n = 10_000_000;
// Sequential Stream
long startTime = System.currentTimeMillis();
long sequentialSum = LongStream.rangeClosed(1, n).sum();
long endTime = System.currentTimeMillis();
System.out.println("Sequential Stream Time: " + (endTime - startTime) + " ms");
// Parallel Stream
startTime = System.currentTimeMillis();
long parallelSum = LongStream.rangeClosed(1, n).parallel().sum();
endTime = System.currentTimeMillis();
System.out.println("Parallel Stream Time: " + (endTime - startTime) + " ms");
}
}
সম্ভাব্য আউটপুট:
Sequential Stream Time: 120 ms
Parallel Stream Time: 45 ms
বিশ্লেষণ:
- Parallel Stream বড় ডেটাসেটের জন্য দ্রুত কাজ সম্পন্ন করে।
- ছোট ডেটাসেটের জন্য Sequential Stream ভালো।
Best Practices
- ছোট ডেটাসেটের জন্য Sequential Stream ব্যবহার করুন।
- Parallel Stream ছোট ডেটাসেটে ওভারহেড তৈরি করে।
- Parallel Stream ব্যবহার করার আগে প্রসেসিং টাইম পরিমাপ করুন।
- Parallel Stream বড় ডেটাসেটের জন্যই কার্যকর।
সঠিক অর্ডার প্রয়োজন হলে Parallel Stream এ
forEachOrdered()ব্যবহার করুন।IntStream.range(1, 10) .parallel() .forEachOrdered(System.out::println);- স্টেটলেস অপারেশন নিশ্চিত করুন।
- Parallel Stream এ স্টেটফুল অপারেশন (যেমন গ্লোবাল ভেরিয়েবল পরিবর্তন) সমস্যা তৈরি করতে পারে।
Common Pitfalls
- Incorrect Use of Parallel Stream
- ছোট ডেটাসেট বা কমপ্লেক্স ডেটা প্রসেসিংয়ে Parallel Stream ওভারহেড তৈরি করে এবং পারফরম্যান্স কমায়।
- Unordered Processing
- Parallel Stream উৎস ক্রম বজায় না রাখলে ভুল ফলাফল হতে পারে।
Stateful Lambda Expression
- Parallel Stream এ স্টেটফুল ল্যাম্বডা এক্সপ্রেশন ডেটা ইনকনসিস্টেন্সি সৃষ্টি করতে পারে।
List<Integer> list = new ArrayList<>(); IntStream.range(1, 100).parallel().forEach(list::add); // Unsafe!- ForkJoinPool Overhead
- Parallel Stream অতিরিক্ত থ্রেড ব্যবহারে ForkJoinPool ওভারলোড হতে পারে।
| স্ট্রিম টাইপ | সেরা ব্যবহারের পরিস্থিতি |
|---|---|
| Sequential | ছোট ডেটাসেট, ডিবাগিং সহজ, এবং উৎস ক্রম প্রয়োজন। |
| Parallel | বড় ডেটাসেট এবং মাল্টি-থ্রেড প্রসেসিং যেখানে পারফরম্যান্স গুরুত্বপূর্ণ। |
Sequential এবং Parallel Streams সঠিকভাবে ব্যবহার করলে ডেটা প্রসেসিং আরও কার্যকর এবং কনকারেন্ট অ্যাপ্লিকেশন তৈরি সহজ হয়।
Read more